/*
 * Copyright 2013, NuzoweR@Schneefeuer <nuzower@gmail.com>.
 * The Settlers Online - Combat Simulator (tsosim).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SIMULATOR_H_
#define SIMULATOR_H_

#include "Units.h"
#include "Garrison.h"
#include "CombatLog.h"
#include <ostream>

class Simulator
{
public:

	Simulator();

	enum RandomnessMode { RM_RANDOM, RM_FIXED_ACCURACY, RM_MINMIN, RM_MINMAX, RM_MAXMIN, RM_MAXMAX };


	// ----------------------- //

	bool set_repeats(int repeats);
	void set_modify(bool mod_g1, bool mod_g2);
	void set_print_results(bool stats, bool minmax, bool log);

	bool set_garrisons(Garrison* attacker, Garrison* defender);

	// ----------------------- //

	bool start_combat();

	static bool set_default_repeats(int repeats);

	static void set_ostream(std::string const& filename);
	static std::ostream* get_ostream();

private:

	/**
	 *
	 */
	int  compute_combat(Garrison& player, Garrison& computer, RandomnessMode randmode = RM_RANDOM, int fixed_accuracy_player=0, int fixed_accuracy_computer=0);

	/**
	 * type     : what kind of units attacks
	 * number   : how many units of $type attack
	 * garnison : enemy units -> number of units might change after an attack !!!
	 */
	void compute_attack_on_garrison(Garrison::Group& attacker_unit, Garrison& garnison, RandomnessMode randmode, int fixed_accuracy=0);

	/**
	 *
	 */
	int  compute_attack_on_unitgroup(Garrison::Group& attacker_group, Garrison::Group& unitgroup, RandomnessMode randmode, int fixed_accuracy=0); //const;

private:

	bool logging;

	struct CombatData {
		int round;
		int initiative;
	} CDATA;
	CombatLog LOG;

	struct Parameters {
		Parameters();
		int  repeats;
		bool modify_g1, modify_g2;
		bool print_stats, print_log, print_minmax;
	};

	static Parameters DEFAULT;
	Parameters PARAMS;

	Garrison *g1, *g2;
};


#endif // SIMULATOR_H_
